﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using XM.Comm;

namespace XM
{
    // 注意: 有关启用 IIS6 或 IIS7 经典模式的说明，
    // 请访问 http://go.microsoft.com/?LinkId=9394801

    public class MvcApplication : System.Web.HttpApplication
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
            filters.Add(GlobalFilters.Filters);

            //filters.Add(new HandleErrorAttribute());
            filters.Add(new ExceptionAttribute());
        }

        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                "Default", // 路由名称
                "{controller}/{action}/{id}", // 带有参数的 URL
                new { controller = "H", action = "Index", id = UrlParameter.Optional } // 参数默认值
            );

        }

        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            // 默认情况下对 Entity Framework 使用 LocalDB
            Database.DefaultConnectionFactory = new SqlConnectionFactory(@"Data Source=(localdb)\v11.0; Integrated Security=True; MultipleActiveResultSets=True");

            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);

            // -------------------------------------------------------------------

            //TaskAction.QueryUser();  // 每次启动都执行
            // 定时任务
            System.Timers.Timer myTimer = new System.Timers.Timer(2*3600 * 1000);  // 2小时执行一次
            //TaskAction.SetContent 表示要调用的方法
            myTimer.Elapsed += new System.Timers.ElapsedEventHandler(TaskAction.Run);
            myTimer.Enabled = true;
            myTimer.AutoReset = true;
        }

        protected void Application_End(object sender, EventArgs e)
        {
            // 下面的代码是关键，可解决IIS应用程序池自动回收的问题
            System.Threading.Thread.Sleep(1000);
            // 指向你的任意一个aspx页面甚至不存在的页面，目的是要激发Application_Start
            // 心跳包
            string url = "http://hiv.hsop.site/User/UIA2";
            System.Net.HttpWebRequest myHttpWebRequest = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(url);
            System.Net.HttpWebResponse myHttpWebResponse = (System.Net.HttpWebResponse)myHttpWebRequest.GetResponse();
            System.IO.Stream receiveStream = myHttpWebResponse.GetResponseStream();//得到回写的字节流

            // 在会话结束时运行的代码。
            // 注意: 只有在 Web.config 文件中的 sessionstate 模式设置为 InProc 时，才会引发 Session_End 事件。
            // 如果会话模式设置为 StateServer
            // 或 SQLServer，则不会引发该事件。
        }


        [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
        public class Test1FilterAttribute : ActionFilterAttribute
        {
            public string Message { get; set; }

            public override void OnActionExecuting(ActionExecutingContext filterContext)
            {
                filterContext.HttpContext.Response.Write("Action执行之前" + Message + "<br />");
                filterContext.HttpContext.Response.Write("Action执行之前" + Message + "<br />");
                filterContext.HttpContext.Response.Write("Action执行之前" + Message + "<br />");
                base.OnActionExecuting(filterContext);
                filterContext.HttpContext.Response.Write("Action执行之前" + Message + "<br />");
            }

            public override void OnActionExecuted(ActionExecutedContext filterContext)
            {
                base.OnActionExecuted(filterContext);
                filterContext.HttpContext.Response.Write("Action执行之后" + Message + "<br />");
            }

            public override void OnResultExecuting(ResultExecutingContext filterContext)
            {
                base.OnResultExecuting(filterContext);
                filterContext.HttpContext.Response.Write("返回Result之前" + Message + "<br />");
            }

            public override void OnResultExecuted(ResultExecutedContext filterContext)
            {
                base.OnResultExecuted(filterContext);
                filterContext.HttpContext.Response.Write("返回Result之后" + Message + "<br />");
            }
        }
    }

    #region
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
    public class ExceptionAttribute : FilterAttribute, IExceptionFilter
    {
        public virtual void OnException(ExceptionContext filterContext)
        {
            string message = string.Format("消息类型：{0}<br>消息内容：{1}<br>引发异常的方法：{2}<br>引发异常源：{3}"
                , filterContext.Exception.GetType().Name
                , filterContext.Exception.Message
                 , filterContext.Exception.TargetSite
                 , filterContext.Exception.Source + filterContext.Exception.StackTrace
                 );

            #region 记录错误地址
            string domainName = filterContext.HttpContext.Request.Url.Authority;
            //获取 controllerName 名称
            string controllerName = filterContext.RouteData.Values["controller"].ToString();
            //获取ACTION 名称
            string actionName = filterContext.RouteData.Values["action"].ToString();
            HttpRequestBase bases = (HttpRequestBase)filterContext.HttpContext.Request;
            //获取url中的参数
            string queryString = bases.QueryString.ToString();
            //对获取到的参数进行UrlDecode处理
            queryString = HttpUtility.UrlDecode(queryString);
            string url = domainName + "/" + controllerName + "/" + actionName + "?" + queryString;
            url = "http://" + url;
            HttpContext.Current.Session["BackUrl"] = url;
            #endregion

            HandleException(filterContext.Exception);
            //记录日志
            //WriteLog.WriteInfo(message);

            //抛出异常信息
            filterContext.Controller.TempData["ExceptionAttributeMessages"] = message;

            //转向
            filterContext.ExceptionHandled = true;
            //if (PM.IsMobile())
            //{
            //    filterContext.Result = new RedirectResult("/user/loginW/");
            //}
            //else
            //{
            //    filterContext.Result = new RedirectResult("/user/Login/");
            //}
        }


        #region  创建错误日志
        ///-----------------------------------------------------------------------------
        /// <summary>创建错误日志 在c:\ErrorLog\</summary>
        /// <param name="strFunctionName">strFunctionName,调用方法名</param>
        /// <param name="strErrorNum">strErrorNum,错误号</param>
        /// <param name="strErrorDescription">strErrorDescription,错误内容</param>
        /// <returns></returns>
        /// <history>2009-05-29 Created</history>
        ///-----------------------------------------------------------------------------
        //举例:
        //         try
        //         {    要监视的代码     }
        //      catch()
        //            {  myErrorLog.m_CreateErrorLogTxt("myExecute(" & str执行SQL语句 & ")", Err.Number.ToString, Err.Description)  }     
        //         finally
        //         {            }
        public static void m_CreateErrorLogTxt(string strFunctionName, string strErrorNum, string strErrorDescription)
        {
            string strMatter; //错误内容
            string strPath; //错误文件的路径
            DateTime dt = DateTime.Now;
            try
            {
                //Server.MapPath("./") + "File"; 服务器端路径
                strPath = Directory.GetCurrentDirectory() + "\\ErrorLog";   //winform工程\bin\目录下 创建日志文件夹 
                //strPath = "c:" + "\\ErrorLog";//暂时放在c:下

                if (Directory.Exists(strPath) == false)  //工程目录下 Log目录 '目录是否存在,为true则没有此目录
                {
                    Directory.CreateDirectory(strPath); //建立目录　Directory为目录对象
                }
                strPath = strPath + "\\" + dt.ToString("yyyyMM");

                if (Directory.Exists(strPath) == false)  //目录是否存在  '工程目录下 Log\月 目录   yyyymm
                {
                    Directory.CreateDirectory(strPath);  //建立目录//日志文件，以 日 命名 
                }
                strPath = strPath + "\\" + dt.ToString("dd") + ".txt";

                strMatter = strFunctionName + " , " + strErrorNum + " , " + strErrorDescription;//生成错误信息

                StreamWriter FileWriter = new StreamWriter(strPath, true); //创建日志文件
                FileWriter.WriteLine("Time: " + dt.ToString("HH:mm:ss") + "  Err: " + strMatter);
                FileWriter.Close(); //关闭StreamWriter对象
            }
            catch (Exception ex)
            {
                //("写错误日志时出现问题，请与管理员联系！ 原错误:" + strMatter + "写日志错误:" + ex.Message.ToString());
                string str = ex.Message.ToString();
            }
        }
        #endregion

        //public static void HandleException(Exception ex)
        //{
        //    string pathStr = HttpRuntime.AppDomainAppPath.ToString();
        //    pathStr += "Log\\";
        //    if (!System.IO.Directory.Exists(pathStr))
        //    {
        //        System.IO.Directory.CreateDirectory(pathStr);
        //    }
        //    DateTime now = DateTime.Now;
        //    string logpath = string.Format(@"Error_{0}{1}{2}{3}.logStr", now.Year, now.Month, now.Day, now.Hour);
        //    logpath = pathStr + logpath;
        //    if (!File.Exists(logpath))
        //    {
        //        File.Create(logpath);
        //    }
        //    System.IO.File.AppendAllText(logpath, string.Format("\r\n----------------------{0}--------------------------\r\n", now.ToString("yyyy-MM-dd HH:mm:ss")));
        //    System.IO.File.AppendAllText(logpath, ex.Message);
        //    System.IO.File.AppendAllText(logpath, "\r\n");
        //    System.IO.File.AppendAllText(logpath, ex.StackTrace);
        //    System.IO.File.AppendAllText(logpath, "\r\n");
        //    System.IO.File.AppendAllText(logpath, "\r\n----------------------footer--------------------------\r\n");

        //}
        public static void HandleException(Exception ex)
        {
            //string pathStr = System.Environment.CurrentDirectory;
            string pathStr = HttpRuntime.AppDomainAppPath.ToString();
            pathStr += "\\LogWin\\" + DateTime.Now.Year + "\\" + DateTime.Now.Month + "\\" + DateTime.Now.Day + "\\";
            if (!System.IO.Directory.Exists(pathStr))
            {
                System.IO.Directory.CreateDirectory(pathStr);
            }
            DateTime now = DateTime.Now;
            string logpath = string.Format(@"Error_{0}{1}{2}{3}.log", now.Year, now.Month, now.Day, now.Hour);
            logpath = pathStr + logpath;

            FileInfo finfo = new FileInfo(logpath);
            if (!finfo.Exists)
            {
                FileStream fs;
                fs = File.Create(logpath);
                fs.Close();
                finfo = new FileInfo(logpath);
            }
            using (FileStream fs = finfo.OpenWrite())
            {
                /**/
                ///根据上面创建的文件流创建写数据流
                StreamWriter w = new StreamWriter(fs);
                /**/
                ///设置写数据流的起始位置为文件流的末尾
                w.BaseStream.Seek(0, SeekOrigin.End);
                w.Write("------------------------------------\r\n");
                //w.Write(ex.ToString() + "\r\n");
                //w.Write(ex.ToString() + "\r\n");
                /**/
                ///写入“Log Entry : ”
                w.Write("\n\rLog Entry : ");
                /**/
                ///写入当前系统时间并换行
                w.Write("{0} {1} \r\n", DateTime.Now.ToLongTimeString(),
                    DateTime.Now.ToLongDateString());
                /**/
                ///写入日志内容并换行
                w.Write(ex.ToString() + "\r\n");
                ///**/
                /////写入------------------------------------“并换行
                //w.Write("------------------------------------\r\n");
                //w.Write(ex.ToString() + "\r\n");
                //w.Write(ex.ToString() + "\r\n");
                /**/
                ///清空缓冲区内容，并把缓冲区内容写入基础流
                w.Flush();
                /**/
                ///关闭写数据流
                w.Close();
            }
        }


        // 操作日志
        public static void HandleLog(string log, string user = "")
        {
            string pathStr = HttpRuntime.AppDomainAppPath.ToString();
            pathStr += "\\LogWin\\" + DateTime.Now.ToString("yyyy-MM-dd") + "\\";
            if (!string.IsNullOrWhiteSpace(user))
            {
                pathStr += user + "\\";
            }
            if (!System.IO.Directory.Exists(pathStr))
            {
                System.IO.Directory.CreateDirectory(pathStr);
            }
            DateTime now = DateTime.Now;
            string logpath = string.Format(@"Log_{0}{1}{2}{3}.log", now.Year, now.Month, now.Day, now.Hour);
            logpath = pathStr + logpath;

            FileInfo finfo = new FileInfo(logpath);
            if (!finfo.Exists)
            {
                FileStream fs;
                fs = File.Create(logpath);
                fs.Close();
                finfo = new FileInfo(logpath);
            }
            using (FileStream fs = finfo.OpenWrite())
            {
                // 根据上面创建的文件流创建写数据流
                StreamWriter w = new StreamWriter(fs);

                // 设置写数据流的起始位置为文件流的末尾
                w.BaseStream.Seek(0, SeekOrigin.End);
                w.Write("------------------------------------\r\n");
                // 写入“Log Entry : ”
                w.Write("\n\rLog Entry : ");
                // 写入当前系统时间并换行
                w.Write("{0} {1} \r\n", DateTime.Now.ToLongTimeString(), DateTime.Now.ToLongDateString());
                // 写入日志内容并换行
                w.Write(log + "\r\n");
                // 清空缓冲区内容，并把缓冲区内容写入基础流
                w.Flush();
                // 关闭写数据流
                w.Close();
            }
        }
    }
    #endregion
}